package com.lk.security.authentication.mobile;

import org.springframework.lang.Nullable;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.Assert;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @description: 用于检验用户手机好是否通过认证
 * @author: Aspirin
 * @create: 2020-05-31 09:36
 */
public class MobileAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

  private String mobileParameter = "mobile";
  private boolean postOnly = true;

  public MobileAuthenticationFilter() {
    super(new AntPathRequestMatcher("/mobile/form", "POST"));
  }

  @Override
  public Authentication attemptAuthentication(
      HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
    String requestType = "POST";
    if (postOnly && !requestType.equalsIgnoreCase(request.getMethod())) {
      throw new AuthenticationServiceException(
          "Authentication method not supported: " + request.getMethod());
    }

    String mobile = obtainMobile(request);

    if (mobile == null) {
      mobile = "";
    }

    mobile = mobile.trim();

    MobileAuthenticationToken authRequest = new MobileAuthenticationToken(mobile);

    // sessionID , hostname
    setDetails(request, authRequest);

    return this.getAuthenticationManager().authenticate(authRequest);
  }

  /**
   * 从请求总获取手机号码
   *
   * @param request 请求
   * @return 手机号
   */
  @Nullable
  protected String obtainMobile(HttpServletRequest request) {
    return request.getParameter(mobileParameter);
  }

  /**
   * 将sessionID和hostname添加到MobileAuthenticationToken
   *
   * @param request 请求
   * @param authRequest 验证
   */
  protected void setDetails(HttpServletRequest request, MobileAuthenticationToken authRequest) {
    authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
  }

  public String getMobileParameter() {
    return mobileParameter;
  }

  public void setMobileParameter(String mobileParameter) {
    Assert.hasText(mobileParameter, "mobile parameter must not be empty or null");
    this.mobileParameter = mobileParameter;
  }

  public boolean isPostOnly() {
    return postOnly;
  }

  /**
   * 设置是否是post请求
   *
   * @param postOnly postOnly
   */
  public void setPostOnly(boolean postOnly) {
    this.postOnly = postOnly;
  }
}
